home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1997 April
/
EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso
/
EARCD
/
util
/
wb
/
lupe.lha
/
source
/
lupe.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-18
|
62KB
|
2,351 lines
// Lupe V1.7 - 1995-96 - © Frank Toepper
// a lens
// AmigaOS 3.0+
// Maxon C++ V3
// last changes: 23.October.96
#include <string.h>
#include <iostream.h>
extern "C"
{
#include <clib/alib_protos.h>
}
#include <intuition/intuition.h>
#include <intuition/imageclass.h>
#include <intuition/icclass.h>
#include <intuition/gadgetclass.h>
#include <intuition/intuitionbase.h>
#include <exec/exec.h>
#include <dos/dos.h>
#include <graphics/scale.h>
#include <devices/inputevent.h>
#include <libraries/commodities.h>
#include <libraries/gadtools.h>
#include <datatypes/pictureclass.h>
#include <graphics/displayinfo.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <cybergraphics/cybergraphics.h>
#include <clib/dos_protos.h>
#include <pragma/dos_lib.h>
#include <clib/intuition_protos.h>
#include <pragma/intuition_lib.h>
#include <clib/graphics_protos.h>
#include <pragma/graphics_lib.h>
#include <clib/exec_protos.h>
#include <pragma/exec_lib.h>
#include <clib/commodities_protos.h>
#include <pragma/commodities_lib.h>
#include <clib/gadtools_protos.h>
#include <pragma/gadtools_lib.h>
#include <clib/icon_protos.h>
#include <pragma/icon_lib.h>
#include <clib/cybergraphics_protos.h>
#include <pragma/cybergraphics_lib.h>
#include <clib/wb_protos.h>
#include <pragma/wb_lib.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <pragma/asl_lib.h>
#include <wbstartup.h>
#pragma header
#define VERSION "Lupe V1.7"
#define CYBERARRAY_BPP 3
#define MINWIDTH 56
#define MINHEIGHT 30
UWORD innerwidth = 150, innerheight = 100, sourcewidth, sourceheight;
UWORD scalefac = 5, maxscalefac = 15, minwidth, fixedX = 0, fixedY = 0;
UWORD leftoff, topoff, bottomoff, rightoff;
UWORD sizeiw, sizeih, winx, winy, winleft = 0, wintop = 11, originX = 0, originY = 0;
UWORD textoff, coordsstringlen, fontX, fontY, oldx, oldy, scrdepth;
ULONG cxsigflag, waitmask = 0, pens[6];
APTR VisualInfo, cyberdata = NULL;
BPTR fh;
struct MsgPort *broker_mp, *userport, *app_mp = NULL;
struct Task *thistask;
struct Window *mywin;
struct Screen *scr = NULL, *tmpscr;
struct Menu *menu = NULL;
struct MenuItem *item;
struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm, *maskbm = NULL;
struct TextFont *screenfont = NULL, *topazfont;
struct InputXpression setoriginix, resetoriginix, showhideix;
struct RastPort *scrrp, destrp, *winrp, maskrp;
struct Library *CxBase, *GadToolsBase, *CyberGfxBase, *IconBase, *WorkbenchBase, *AslBase;
struct GfxBase *GfxBase;
struct AppIcon *appicon = NULL;
struct AppMessage *appmsg;
struct DiskObject *icon = NULL;
UBYTE timesig, showhidesig;
BOOL hires, newlook, jump = FALSE, fast = FALSE, pubscreenlocked = FALSE, enable = TRUE;
BOOL cybergfxscreen, coords = FALSE, crosshair = FALSE, origin = TRUE, fixed = FALSE;
BOOL jumpdirect, showhide = TRUE, hide = FALSE, hideonclose = FALSE, grid = FALSE, showrgb = FALSE;
CxObj *broker, *customcxobj;
Object *propgadget;
char pubscreenname[MAXPUBSCREENNAME];
char setoriginkey[50] = "lalt o", resetoriginkey[50] = "lalt r", showhidekey[50] = "lalt h";
char title[10], dispstring[12];
char programname[110], iffpath[256] = "ram:Lupe.iff", iffname[110];
char *Template = "CX_PRIORITY=P/N/K, FAST=F/S/K, MAXSCALEFACTOR=M/N/K, SCALEFACTOR=S/N/K, "
"WINLEFT=L/N/K, WINTOP=T/N/K, WINWIDTH=W/N/K, WINHEIGHT=H/N/K, "
"COORDINATES=C/S/K, CROSSHAIR=R/S/K, SETORIGINKEY=O/K, RESETORIGINKEY=K/K, "
"FIXED=D/S/K, SHOWHIDEKEY=SH/K, ICONIFY=I/S/K, ICONIFYONCLOSE=IOC/S/K, "
"GRID=G/S/K, SHOWRGB=RGB/S/K, IFFFILE=IF/K";
extern struct IntuitionBase *IntuitionBase;
// function declarations for menu
BOOL jumpFunc ();
BOOL saveFunc ();
BOOL fastFunc ();
BOOL AboutFunc ();
BOOL enableFunc ();
BOOL coordsFunc ();
BOOL crosshairFunc ();
BOOL gridFunc ();
BOOL showrgbFunc ();
BOOL fixedFunc ();
BOOL QuitFunc ();
BOOL hideFunc ();
BOOL hideoncloseFunc ();
struct NewMenu standartmenu[] = {
{ NM_TITLE, "Project", 0, 0, 0, 0 },
{ NM_ITEM, "Jump", "J", 0, 0, jumpFunc },
{ NM_ITEM, "Jump To Screen", 0, 0, 0, 0 },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "Save IFF...", "S", 0, 0, saveFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "Enable", "E", CHECKIT | MENUTOGGLE, 0, enableFunc },
{ NM_ITEM, "Fixed", "D", CHECKIT | MENUTOGGLE, 0, fixedFunc },
{ NM_ITEM, "Fast", "F", CHECKIT | MENUTOGGLE, 0, fastFunc },
{ NM_ITEM, "Coordinates", "C", CHECKIT | MENUTOGGLE, 0, coordsFunc },
{ NM_ITEM, "Crosshair", "R", CHECKIT | MENUTOGGLE, 0, crosshairFunc },
{ NM_ITEM, "Grid", "G", CHECKIT | MENUTOGGLE, 0, gridFunc },
{ NM_ITEM, "Show RGB", "W", CHECKIT | MENUTOGGLE, 0, showrgbFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "About", "?", 0, 0, AboutFunc },
{ NM_ITEM, NM_BARLABEL, 0, 0, 0, 0 },
{ NM_ITEM, "Iconify On Close", "N", CHECKIT | MENUTOGGLE, 0, hideoncloseFunc },
{ NM_ITEM, "Iconify", "I", 0, 0, hideFunc },
{ NM_ITEM, "Quit", "Q", 0, 0, QuitFunc },
{ NM_END, 0, 0, 0, 0, 0 }
};
struct EasyStruct es_about = {
20, 0,
"Lupe",
"%s",
"%s"
};
char *era_about[] = {
VERSION " (" __DATE__ ")\n\n"
"written by:\n"
" Frank Toepper\n"
" Maxim Gorki Straße 5A\n"
" Greifswald\n"
" 17491\n"
" GERMANY\n\n"
"E-Mail:\n"
" toepper@rz.uni-greifswald.de\n"
"WWW:\n"
" http://www.user.fh-stralsund.de/~rwermke/di.html\n\n"
"This program is Public Domain",
"Ok"
};
struct NewBroker newbroker = {
NB_VERSION,
"Lupe",
VERSION " © 1995-96 Frank Toepper",
"A magnifying glass program.",
3,
COF_SHOW_HIDE,
0,
NULL,
0
};
struct BitScaleArgs bsa = {
// Src Koords
0, 0,
innerwidth / scalefac,
innerheight / scalefac,
// Src Faktoren
1, 1,
0, 0,
innerwidth,
innerheight,
// Dest Faktoren
scalefac, scalefac,
// Bitmaps
NULL, NULL,
0,
0, 0,
0, 0
};
struct TextAttr topaz_attr = {
"topaz.font",
8,
0,
FPF_ROMFONT
};
void Putchar (register __d0 char zeichen, register __a3 char *putchdata)
{
*putchdata++ = zeichen;
}
void error (char *formatstring, ...)
{
APTR args = &formatstring + 1;
struct EasyStruct easystruct = {
sizeof (struct EasyStruct),
0,
"Error",
formatstring,
"Ok"
};
if (Cli ())
{
VPrintf (formatstring, (LONG *) args);
FPutC (Output (), '\n');
Flush (Output ());
}
else
{
EasyRequestArgs (NULL, &easystruct, NULL, args);
}
}
BOOL lockaspublicscreen (struct Screen *screen)
{
struct List *pubscreenlist;
struct PubScreenNode *pubscreennode;
pubscreenlist = LockPubScreenList ();
if (pubscreenlist)
{
pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
while (pubscreennode)
{
if (pubscreennode->psn_Screen == screen)
{
if (LockPubScreen (pubscreennode->psn_Node.ln_Name))
{
UnlockPubScreenList ();
return TRUE;
}
}
pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
}
UnlockPubScreenList ();
}
return FALSE;
}
int setupscreen (struct Screen *selectedscreen)
{
ULONG id;
jumpdirect = FALSE;
if (selectedscreen)
{
jumpdirect = TRUE;
if (scr)
{
if (VisualInfo)
{
FreeVisualInfo (VisualInfo);
}
if (pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
}
}
if (lockaspublicscreen (selectedscreen))
{
pubscreenlocked = TRUE;
}
else
{
pubscreenlocked = FALSE;
}
scr = selectedscreen;
}
else if (scr)
{
tmpscr = scr->NextScreen;
if (tmpscr)
{
FreeVisualInfo (VisualInfo);
VisualInfo = NULL;
if (pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
pubscreenlocked = FALSE;
}
if (lockaspublicscreen (tmpscr))
{
pubscreenlocked = TRUE;
}
}
else
{
error ("There is no other screen.");
return 1; // not real an error
}
scr = tmpscr;
}
else if ((scr = LockPubScreen (NULL)) != 0)
{
pubscreenlocked = TRUE;
}
else
{
error ("Can't lock publicscreen.");
return 2;
}
VisualInfo = GetVisualInfoA (scr, NULL);
if (!VisualInfo)
{
error ("Can't get visualinfo from screen.");
return 3;
}
cybergfxscreen = FALSE;
if (CyberGfxBase)
if ((id = GetVPModeID (&scr->ViewPort)) != INVALID_ID)
if (IsCyberModeID (id))
if (GetCyberIDAttr (CYBRIDATTR_BPPIX, id) > 1)
cybergfxscreen = TRUE;
return 0;
}
void CloseDownScreen ()
{
if (VisualInfo)
{
FreeVisualInfo (VisualInfo);
VisualInfo = NULL;
}
if (scr && pubscreenlocked)
{
UnlockPubScreen (NULL, scr);
pubscreenlocked = FALSE;
}
}
void getoffsets ()
{
struct DrawInfo *drawinfo;
APTR sizeobject;
ULONG attr;
if (screenfont)
{
CloseFont (screenfont);
screenfont = NULL;
}
hires = (scr->Flags & SCREENHIRES) != 0;
hires ? (rightoff = 18) : (rightoff = 13);
SetAPen (&maskrp, 1);
drawinfo = GetScreenDrawInfo (scr);
if (drawinfo)
{
sizeobject = NewObject (NULL, SYSICLASS,
SYSIA_Which, SIZEIMAGE, SYSIA_DrawInfo, drawinfo,
SYSIA_Size, hires ? SYSISIZE_MEDRES : SYSISIZE_LOWRES, TAG_END);
if (sizeobject)
{
if (GetAttr (IA_Width, sizeobject, &attr))
{
sizeiw = attr;
rightoff = (UWORD) attr;
}
if (GetAttr (IA_Height, sizeobject, &attr))
{
sizeih = attr;
}
newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
SetAPen (&maskrp, drawinfo->dri_Pens[SHADOWPEN]);
DisposeObject (sizeobject);
}
pens[0] = drawinfo->dri_Pens[FILLTEXTPEN];
pens[1] = drawinfo->dri_Pens[FILLPEN];
pens[2] = drawinfo->dri_Pens[TEXTPEN];
pens[3] = drawinfo->dri_Pens[BACKGROUNDPEN];
pens[4] = drawinfo->dri_Pens[SHINEPEN];
pens[5] = drawinfo->dri_Pens[SHADOWPEN];
FreeScreenDrawInfo (scr, drawinfo);
}
else
{
// default pens
pens[0] = 2;
pens[1] = 3;
pens[2] = 1;
pens[3] = 0;
pens[4] = 2;
pens[5] = 1;
} // if (drawinfo)
scrrp = &scr->RastPort;
topoff = scrrp->TxHeight + (UWORD) scr->WBorTop + 1;
leftoff = scr->WBorLeft;
scrbm = scrrp->BitMap;
scrdepth = GetBitMapAttr (scrbm, BMA_DEPTH);
fontX = topazfont->tf_XSize;
fontY = topazfont->tf_YSize;
minwidth = MINWIDTH;
coordsstringlen = 1;
if (scr->Width > 999)
{
coordsstringlen += 5;
}
else
{
coordsstringlen += 4;
}
if (scr->Height > 999)
{
coordsstringlen += 5;
}
else
{
coordsstringlen += 4;
}
if (coords || showrgb)
{
bottomoff = sizeih;
// center the text in the bottomborder
textoff = (bottomoff + fontY >> 1) - topazfont->tf_Baseline;
minwidth = 0;
if (coords)
{
minwidth = coordsstringlen * (fontX);
}
if (showrgb)
{
minwidth += 13 * (fontX);
}
// SysIHack or height of screenfont <= 8?
if ((bottomoff - 2) >= scr->Font->ta_YSize)
{
screenfont = OpenFont (scr->Font);
if (screenfont)
{
if (!(screenfont->tf_Flags & FPF_PROPORTIONAL))
{
fontX = screenfont->tf_XSize;
fontY = screenfont->tf_YSize;
minwidth = 0;
if (coords)
{
minwidth = coordsstringlen * (fontX);
}
if (showrgb)
{
minwidth += 13 * (fontX);
}
// center the text in the bottomborder
textoff = (bottomoff + fontY >> 1) - screenfont->tf_Baseline;
}
else
{
CloseFont (screenfont);
screenfont = NULL;
}
}
}
} // if (coords
else
{
bottomoff = scr->WBorBottom;
}
}
void setwintitle ()
{
LONG args[] = { (LONG) "Lupe", scalefac };
RawDoFmt ("%s %ld:1", args, (void (*)()) Putchar, title);
SetWindowTitles (mywin, title, (STRPTR) ~0);
}
void setmenu ()
{
struct MenuItem *mitem;
if (mywin)
{
ClearMenuStrip (mywin);
mitem = ItemAddress (menu, FULLMENUNUM (0, 3, NOSUB));
if (scalefac > 1) mitem->Flags |= ITEMENABLED;
else mitem->Flags &= ~ITEMENABLED;
mitem = ItemAddress (menu, FULLMENUNUM (0, 5, NOSUB));
if (enable) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (fixed) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (fast) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (coords) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (crosshair) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (grid) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = mitem->NextItem;
if (showrgb) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
mitem = ItemAddress (menu, FULLMENUNUM (0, 15, NOSUB));
if (hideonclose) mitem->Flags |= CHECKED;
else mitem->Flags &= ~CHECKED;
ResetMenuStrip (mywin, menu);
}
}
void setupgrid ()
{
if (maskbm)
{
FreeBitMap (maskbm);
maskbm = NULL;
}
if (grid)
{
maskbm = AllocBitMap (innerwidth, innerheight, 1, BMF_CLEAR, destbm);
if (!maskbm)
{
error ("'AllocBitMap' for grid mask failed.");
grid = FALSE;
setmenu ();
}
else
{
LONG i, j;
maskrp.BitMap = maskbm;
for (i = scalefac - 1; i < innerwidth; i += scalefac)
{
RectFill (&maskrp, i, 0, i, innerheight - 1)
}
for (i = scalefac - 1; i < innerheight; i += scalefac)
{
for (j = 0; j < innerwidth; j += scalefac)
{
RectFill (&maskrp, j, i, j + scalefac - 2, i);
}
}
}
}
}
int allocbm ()
{
if (destbm)
{
FreeBitMap (destbm);
destbm = NULL;
}
if (srcbm)
{
FreeBitMap (srcbm);
srcbm = NULL;
}
if (cyberdata)
{
FreeVec (cyberdata);
cyberdata = NULL;
}
winx = mywin->Width;
winy = mywin->Height;
innerwidth = winx - (leftoff + rightoff);
innerheight = winy - (topoff + bottomoff);
sourcewidth = innerwidth / scalefac;
sourceheight = innerheight / scalefac;
if (scalefac > 1)
{
if (cybergfxscreen)
{
if (!(cyberdata = AllocVec (sourcewidth * sourceheight * CYBERARRAY_BPP, MEMF_PUBLIC)))
{
error ("Can't allocate %ld Bytes for CyberPixelArray.", sourcewidth * sourceheight * CYBERARRAY_BPP);
return 1;
}
if (!(destbm = AllocBitMap (innerwidth, innerheight, 24, BMF_CLEAR | BMF_MINPLANES | PIXFMT_RGB24, 0)))
{
error ("'AllocBitMap' for destination bitmap failed.");
return 2;
}
}
else
{
if (!(srcbm = AllocBitMap (sourcewidth, sourceheight, scrdepth, BMF_CLEAR, scrbm)))
{
error ("'AllocBitMap' for source bitmap failed.");
return 3;
}
if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, srcbm)))
{
error ("'AllocBitMap' for destination bitmap failed.");
return 4;
}
bsa.bsa_SrcWidth = sourcewidth;
bsa.bsa_SrcHeight = sourceheight;
bsa.bsa_DestWidth = innerwidth;
bsa.bsa_DestHeight = innerheight;
bsa.bsa_SrcBitMap = srcbm;
bsa.bsa_DestBitMap = destbm;
bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
}
setupgrid ();
destrp.BitMap = destbm;
}
return 0;
}
BOOL makescreensmenu ()
{
struct NewMenu tmpmenu[] = {
{ NM_SUB, 0, 0, 0, 0, 0 },
{ NM_END, 0, 0, 0, 0, 0 }
};
ULONG lock;
struct List *pubscreenlist;
struct PubScreenNode *pubscreennode;
struct MenuItem **itempointer = &menu->FirstItem->NextItem->SubItem;
lock = LockIBase (0);
tmpscr = IntuitionBase->FirstScreen;
if (tmpscr->NextScreen)
{
while ((tmpscr = tmpscr->NextScreen) != 0)
{
tmpmenu[0].nm_Label = tmpscr->DefaultTitle;
pubscreenlist = LockPubScreenList ();
if (pubscreenlist)
{
pubscreennode = (struct PubScreenNode *) pubscreenlist->lh_Head;
while (pubscreennode)
{
if (pubscreennode->psn_Screen == tmpscr)
{
tmpmenu[0].nm_Label = pubscreennode->psn_Node.ln_Name;
break;
}
pubscreennode = (struct PubScreenNode *) pubscreennode->psn_Node.ln_Succ;
}
UnlockPubScreenList ();
}
tmpmenu[0].nm_UserData = tmpscr;
// each item single created
*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
if (*itempointer)
{
itempointer = &(*itempointer)->NextItem;
}
else
{
error ("Can't create a screensmenu item.");
}
}
}
else
{
tmpmenu[0].nm_Label = "No Other Screen";
*itempointer = (struct MenuItem *) CreateMenusA (tmpmenu, NULL);
if (*itempointer)
{
(*itempointer)->Flags |= HIGHNONE;
itempointer = &(*itempointer)->NextItem;
}
else
{
error ("Can't create screensmenu.");
}
}
UnlockIBase (lock);
if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
{
return TRUE;
}
else
{
error ("Can't layout screensmenu.");
}
return FALSE;
}
void freescreensmenu (struct MenuItem *menuitem)
{
if (menuitem)
{
freescreensmenu (menuitem->NextItem);
FreeMenus ((struct Menu *) menuitem);
}
}
BOOL openwin ()
{
ULONG lock;
WORD bw, rh;
struct Rectangle zoom = {
minwidth + leftoff + rightoff,
MINHEIGHT + topoff + bottomoff + sizeih,
-1, -1
};
if (!mywin)
{
if (hires)
{
bw = rh = 2;
}
else
{
bw = rh = 1;
}
// first bring the screen to front
// -> screen order in menu correct
lock = LockIBase (0);
tmpscr = IntuitionBase->FirstScreen;
UnlockIBase (lock);
if (tmpscr != scr)
{
if (jumpdirect)
{
ScreenToFront (scr);
}
else
{
ScreenToBack (tmpscr);
}
}
menu = CreateMenusA (standartmenu, NULL);
if (menu)
{
if (makescreensmenu ())
{
propgadget = (Object *) NewObject (NULL, PROPGCLASS,
PGA_Freedom, FREEVERT,
ICA_TARGET, ICTARGET_IDCMP,
PGA_NewLook, TRUE,
PGA_Borderless, newlook,
PGA_Total, maxscalefac,
PGA_Visible, 1,
PGA_Top, scalefac - 1,
GA_RelRight, bw - sizeiw + 3,
GA_Top, topoff + rh,
GA_Width, sizeiw - bw - bw - 4,
GA_RelHeight, -topoff - sizeih - rh - rh,
GA_RightBorder, TRUE,
TAG_DONE);
if (propgadget)
{
if (innerwidth < minwidth)
{
innerwidth = minwidth;
}
mywin = OpenWindowTags (NULL,
WA_Flags, WFLG_ACTIVATE | WFLG_CLOSEGADGET | WFLG_DEPTHGADGET
| WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_SIMPLE_REFRESH
| WFLG_NEWLOOKMENUS | WFLG_REPORTMOUSE | WFLG_SIZEBRIGHT
| ((coords || showrgb) ? WFLG_SIZEBBOTTOM : 0),
WA_AutoAdjust, 1,
WA_MaxHeight, 10000,
WA_MaxWidth, 10000,
WA_MinHeight, MINHEIGHT + topoff + bottomoff,
WA_MinWidth, minwidth + leftoff + rightoff,
WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_IDCMPUPDATE | IDCMP_NEWSIZE
| IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW
| IDCMP_INACTIVEWINDOW | IDCMP_MOUSEBUTTONS
| IDCMP_MOUSEMOVE | IDCMP_VANILLAKEY | IDCMP_RAWKEY
| IDCMP_REFRESHWINDOW,
WA_InnerHeight, innerheight,
WA_InnerWidth, innerwidth,
WA_Left, winleft,
WA_Gadgets, propgadget,
WA_Top, wintop,
WA_PubScreen, scr,
WA_Zoom, &zoom,
TAG_DONE);
if (mywin)
{
// shit patches
leftoff = mywin->BorderLeft;
bottomoff = mywin->BorderBottom;
SetMenuStrip (mywin, menu);
setmenu ();
setwintitle ();
userport = mywin->UserPort;
winrp = mywin->RPort;
if (screenfont)
{
SetFont (winrp, screenfont);
}
else
{
SetFont (winrp, topazfont);
}
SetAPen (winrp, pens[0]);
SetBPen (winrp, pens[1]);
waitmask |= 1 << userport->mp_SigBit;
return TRUE;
}
else
{
error ("Can't open window.");
}
}
else
{
error ("Can't create propgadget.");
}
}
}
else
{
error ("Can't create menu.");
}
return FALSE;
}
return TRUE; // win already open
}
void closewin ()
{
if (mywin)
{
if (menu)
{
ClearMenuStrip (mywin);
}
wintop = mywin->TopEdge;
winleft = mywin->LeftEdge;
waitmask &= ~(1 << userport->mp_SigBit);
CloseWindow (mywin);
mywin = NULL;
userport = NULL;
}
if (menu)
{
freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
FreeMenus (menu);
menu = NULL;
}
if (propgadget)
{
DisposeObject (propgadget);
propgadget = NULL;
}
if (srcbm)
{
FreeBitMap (srcbm);
srcbm = NULL;
}
if (destbm)
{
FreeBitMap (destbm);
destbm = NULL;
}
if (maskbm)
{
FreeBitMap (maskbm);
maskbm = NULL;
}
if (cyberdata)
{
FreeVec (cyberdata);
cyberdata = NULL;
}
}
BOOL screen_is_still_open ()
{
tmpscr = IntuitionBase->FirstScreen;
while (tmpscr)
{
if (tmpscr == scr)
{
return TRUE;
}
tmpscr = tmpscr->NextScreen;
}
return FALSE;
}
void freeappicon ()
{
if (appicon)
{
RemoveAppIcon (appicon);
appicon = NULL;
}
if (app_mp)
{
waitmask &= ~(1 << app_mp->mp_SigBit);
DeleteMsgPort (app_mp);
app_mp = NULL;
}
if (icon)
{
FreeDiskObject (icon);
icon = NULL;
}
}
BOOL showwindow ()
{
if (!mywin)
{
if (!screen_is_still_open ()) scr = NULL;
{
if (setupscreen (scr))
{
return FALSE;
}
getoffsets ();
if (!openwin ())
{
return FALSE;
}
if (allocbm ())
{
return FALSE;
}
}
freeappicon ();
}
return TRUE;
}
void hidewindow ()
{
closewin ();
CloseDownScreen ();
freeappicon ();
if (Cli ())
{
GetProgramName (programname, 108);
}
else
{
strncpy (programname, thistask->tc_Node.ln_Name, 108);
}
if ((icon = GetDiskObject ("ENV:sys/def_Lupe")) == 0)
{
if ((icon = GetDiskObject (programname)) == 0)
{
icon = GetDefDiskObject (WBTOOL);
}
}
if (icon)
{
app_mp = CreateMsgPort ();
if (app_mp)
{
appicon = AddAppIcon (1, 0, "Lupe", app_mp, NULL, icon, NULL);
if (appicon)
{
waitmask |= 1 << app_mp->mp_SigBit;
}
}
}
}
void printcoords (LONG x, LONG y)
{
char dispstring[12];
LONG args[] = {x - originX, y - originY};
if (coords)
{
memset (dispstring, ' ', coordsstringlen);
RawDoFmt ("%ld,%ld", args, (void (*)()) Putchar, dispstring);
dispstring[strlen (dispstring)] = ' ';
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
Move (winrp, leftoff, mywin->Height - textoff);
Text (winrp, dispstring, coordsstringlen);
}
mywin->Flags |= SIZEGADGET;
}
}
void printrgb (LONG x, LONG y)
{
ULONG colorreg, colors[3], apen, color, textlen;
char dispstring[12];
if (showrgb)
{
colorreg = ReadPixel (scrrp, x, y);
if (cybergfxscreen)
{
color = ReadRGBPixel (scrrp, x, y);
colors[0] = (color >> 16) & 0xff;
colors[1] = (color >> 8) & 0xff;
colors[2] = color & 0xff;
}
else
{
GetRGB32 (scr->ViewPort.ColorMap, colorreg, 1, colors);
colors[0] &= 0xff;
colors[1] &= 0xff;
colors[2] &= 0xff;
}
RawDoFmt ("%3ld,%3ld,%3ld", colors, (void (*)()) Putchar, dispstring);
textlen = TextLength (winrp, dispstring, 11);
apen = GetAPen (winrp);
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
Move (winrp, innerwidth - textlen, mywin->Height - textoff);
Text (winrp, dispstring, 11);
SetAPen (winrp, pens[5]);
Move (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - 2);
Draw (winrp, innerwidth - textlen - fontX - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY);
Draw (winrp, innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - fontY);
SetAPen (winrp, pens[4]);
Move (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1);
Draw (winrp, innerwidth - textlen - 1, mywin->Height - (bottomoff - fontY >> 1) - 1);
Draw (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - 1);
SetAPen (winrp, colorreg);
RectFill (winrp, innerwidth - textlen - fontX, mywin->Height - (bottomoff - fontY >> 1) - fontY + 1,
innerwidth - textlen - 2, mywin->Height - (bottomoff - fontY >> 1) - 2);
}
mywin->Flags |= SIZEGADGET;
SetAPen (winrp, apen);
} // if (showrgb)
}
void refresh ()
{
LONG x, y, xoff = 0, yoff = 0;
if (mywin)
{
// set the coordinates
if (enable)
{
if (fixed)
{
x = fixedX;
y = fixedY;
}
else
{
x = scr->MouseX;
y = scr->MouseY;
}
oldx = x;
oldy = y;
}
else
{
x = oldx;
y = oldy;
}
printcoords (x, y);
printrgb (x, y);
// adjust the coordinates
x -= sourcewidth >> 1;
y -= sourceheight >> 1;
if (x < 0)
{
xoff = x;
x = 0;
}
else if (x > (scr->Width - sourcewidth))
{
xoff = -(scr->Width - sourcewidth - x);
x = scr->Width - sourcewidth;
}
if (y < 0)
{
yoff = y;
y = 0;
}
else if (y > (scr->Height - sourceheight))
{
yoff = -(scr->Height - sourceheight - y);
y = scr->Height - sourceheight;
}
// calculate the crosshair
if (crosshair)
{
xoff = scalefac * ((sourcewidth >> 1) + xoff) + (scalefac >> 1);
yoff = scalefac * ((sourceheight >> 1) + yoff) + (scalefac >> 1);
}
if (scalefac > 1)
{
// blit and scale
if (cybergfxscreen)
{
// BitMapScale don't work with bitmaps >8 Bit (CyberGfx 2.15)
ReadPixelArray (cyberdata, 0, 0, sourcewidth * CYBERARRAY_BPP, scrrp, x, y, sourcewidth, sourceheight, RECTFMT_RGB);
ScalePixelArray (cyberdata, sourcewidth, sourceheight, sourcewidth * CYBERARRAY_BPP, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac, RECTFMT_RGB);
}
else
{
BltBitMap (scrbm, x, y, srcbm, 0, 0, sourcewidth, sourceheight, ABNC | ABC, ~0, NULL);
BitMapScale (&bsa);
}
// draw the grid
if (grid)
{
SetDrMd (&destrp, JAM1);
BltTemplate (maskbm->Planes[0], 0, maskbm->BytesPerRow, &destrp, 0, 0, sourcewidth * scalefac, sourceheight * scalefac);
}
// draw the crosshair
if (crosshair)
{
SetDrMd (&destrp, COMPLEMENT);
Move (&destrp, xoff, 0);
Draw (&destrp, xoff, sourceheight * scalefac - 1);
Move (&destrp, 0, yoff);
Draw (&destrp, sourcewidth * scalefac - 1, yoff);
}
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
}
mywin->Flags |= SIZEGADGET;
}
else // 1:1 - mode
{
mywin->Flags &= ~SIZEGADGET;
if ((winx == mywin->Width) && (winy == mywin->Height))
{
BltBitMapRastPort (scrbm, x, y, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
// draw the crosshair in 1:1 - mode
if (crosshair)
{
SetDrMd (winrp, COMPLEMENT);
Move (winrp, leftoff + xoff, topoff);
Draw (winrp, leftoff + xoff, topoff + innerheight - 1);
Move (winrp, leftoff, topoff + yoff);
Draw (winrp, leftoff + innerwidth - 1, topoff + yoff);
SetDrMd (winrp, JAM2);
}
}
mywin->Flags |= SIZEGADGET;
}
}
}
void CxFunction (CxMsg *cxm, CxObj *co)
{
struct InputEvent *ie = (struct InputEvent *) CxMsgData (cxm);
if (origin)
{
if (MatchIX (ie, &setoriginix))
{
originX = scr->MouseX;
originY = scr->MouseY;
DisposeCxMsg (cxm);
return;
}
if (MatchIX (ie, &resetoriginix))
{
originX = originY = 0;
DisposeCxMsg (cxm);
return;
}
}
if (showhide)
{
if (MatchIX (ie, &showhideix))
{
Signal (thistask, 1 << showhidesig);
}
}
if ((ie->ie_Class == IECLASS_TIMER) || fast)
{
Signal (thistask, 1 << timesig);
}
}
BOOL initbroker ()
{
LONG errorcode;
broker_mp = CreateMsgPort ();
if (broker_mp)
{
newbroker.nb_Port = broker_mp;
cxsigflag = 1 << broker_mp->mp_SigBit;
broker = CxBroker (&newbroker, &errorcode);
if (broker)
{
customcxobj = CxCustom (CxFunction, 0);
if (customcxobj)
{
if (!CxObjError (customcxobj))
{
AttachCxObj (broker, customcxobj);
if (ParseIX (setoriginkey, &setoriginix) || ParseIX (resetoriginkey, &resetoriginix))
{
origin = FALSE;
error ("Can't init a Hotkey.\n%s disabled.", "'Set Origin'");
}
if (ParseIX (showhidekey, &showhideix))
{
showhide = FALSE;
error ("Can't init a Hotkey.\n%s disabled.", "'Show/Hide Window'");
}
ActivateCxObj (broker, 1);
return TRUE;
}
DeleteCxObj (customcxobj);
}
else
{
error ("Can't create commodity-custom-objekt.");
}
DeleteCxObjAll (broker);
}
else if (errorcode == CBERR_SYSERR)
{
error ("Can't create commodity-broker-objekt.");
}
DeleteMsgPort (broker_mp);
}
else
{
error ("Can't create messageport for commodity-broker");
}
return FALSE;
}
BOOL reopenwin ()
{
closewin ();
jump = TRUE;
getoffsets ();
if (!openwin ())
{
return FALSE;
}
if (allocbm ())
{
return FALSE;
}
return TRUE;
}
BOOL setpropgad ()
{
if (allocbm ())
{
return FALSE;
}
SetAttrs (propgadget, PGA_Top, scalefac - 1);
RefreshGList ((struct Gadget *) propgadget, mywin, NULL, 1);
setwintitle ();
return TRUE;
}
BOOL menupick (UWORD code)
{
BOOL returnvalue = TRUE;
static BOOL (*func)();
while ((code != MENUNULL) && returnvalue && !jump)
{
item = ItemAddress (menu, code);
if (SUBNUM (code) != NOSUB)
{
if (GTMENUITEM_USERDATA (item)) // 'no other screen'-submenu == 0
{
if (setupscreen ((struct Screen *) GTMENUITEM_USERDATA (item)))
{
return FALSE;
}
closewin ();
jump = TRUE;
getoffsets ();
if (!openwin ())
{
return FALSE;
}
if (allocbm ())
{
return FALSE;
}
}
}
else
{
func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
returnvalue = func ();
}
if (!jump) code = item->NextSelect;
}
return returnvalue;
}
BOOL vanillakey (UWORD code)
{
BOOL returnvalue = TRUE;
switch (code)
{
case 'J':
case 'j':
returnvalue = jumpFunc ();
break;
case 'S':
case 's':
returnvalue = saveFunc ();
break;
case 'E':
case 'e':
enable = !enable;
ActivateCxObj (broker, enable);
setmenu ();
break;
case 'F':
case 'f':
fast = !fast;
setmenu ();
break;
case 'C':
case 'c':
coords = !coords;
returnvalue = reopenwin ();
break;
case 'R':
case 'r':
crosshair = !crosshair;
setmenu ();
break;
case 'O':
case 'o':
originX = scr->MouseX;
originY = scr->MouseY;
break;
case 'K':
case 'k':
originX = originY = 0;
break;
case 'D':
case 'd':
fixed = !fixed;
fixedX = scr->MouseX;
fixedY = scr->MouseY;
setmenu ();
break;
case '?':
case 'A':
case 'a':
returnvalue = AboutFunc ();
break;
case 'N':
case 'n':
hideonclose = !hideonclose;
setmenu ();
break;
case 'I':
case 'i':
returnvalue = hideFunc ();
break;
case 'G':
case 'g':
grid = !grid;
setupgrid ();
setmenu ();
break;
case 'W':
case 'w':
showrgb = !showrgb;
returnvalue = reopenwin ();
break;
case 'Q':
case 'q':
returnvalue = FALSE;
break;
case 27: // ESC
if (hideonclose)
{
hidewindow ();
jump = TRUE;
}
else
{
returnvalue = FALSE;
}
break;
case '+':
if (scalefac < maxscalefac)
{
scalefac++;
returnvalue = setpropgad ();
}
break;
case '-':
if (scalefac > 1)
{
scalefac--;
returnvalue = setpropgad ();
}
break;
}
return returnvalue;
}
void rawkey (UWORD code, UWORD qualifier)
{
BOOL returnvalue = TRUE;
switch (code)
{
// up
case 76:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedY -= sourceheight - 1;
if (fixedY < 0) fixedY = 0;
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedY = 0;
}
else if (fixedY) fixedY--;
break;
// down
case 77:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedY += sourceheight - 1;
if (fixedY > (scr->Height - 1)) fixedY = scr->Height - 1;
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedY = scr->Height - 1;
}
else if (fixedY < (scr->Height - 1)) fixedY++;
break;
// right
case 78:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedX += sourcewidth - 1;
if (fixedX > (scr->Width - 1)) fixedX = scr->Width - 1;
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedX = scr->Width - 1;
}
else if (fixedX < (scr->Width - 1)) fixedX++;
break;
// left
case 79:
if (qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
{
fixedX -= sourcewidth - 1;
if (fixedX < 0) fixedX = 0;
}
else if (qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
{
fixedX = 0;
}
else if (fixedX) fixedX--;
break;
}
}
void processmsg ()
{
struct IntuiMessage *intuimsg = NULL, m;
CxMsg *msg;
BOOL cont = TRUE, fixedmove = FALSE, app_clicked = FALSE;
LONG sigmask, msgid, msgtype;;
ULONG lock;
waitmask |= (1 << timesig) | (1 << showhidesig) | cxsigflag | SIGBREAKF_CTRL_C;
while (cont)
{
sigmask = Wait (waitmask);
if (sigmask & cxsigflag)
{
while ((msg = (CxMsg *) GetMsg (broker_mp)) != 0)
{
msgid = CxMsgID (msg);
msgtype = CxMsgType (msg);
ReplyMsg ((struct Message *) msg);
switch (msgtype)
{
case CXM_COMMAND:
switch (msgid)
{
case CXCMD_APPEAR:
cont = showwindow ();
break;
case CXCMD_DISAPPEAR:
hidewindow ();
break;
case CXCMD_DISABLE:
ActivateCxObj (broker, 0);
enable = FALSE;
setmenu ();
break;
case CXCMD_ENABLE:
ActivateCxObj (broker, 1);
enable = TRUE;
setmenu ();
break;
case CXCMD_UNIQUE:
cont = showwindow ();
break;
case CXCMD_KILL:
cont = FALSE;
break;
}
}
} // while ((msg
}
if (userport)
{
if (sigmask & (1 << userport->mp_SigBit))
{
jump = FALSE;
while ((intuimsg = (struct IntuiMessage *) GetMsg (userport)) != 0)
{
CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
ReplyMsg ((struct Message *) intuimsg);
switch (m.Class)
{
case IDCMP_CLOSEWINDOW:
if (hideonclose)
{
hidewindow ();
}
else
{
cont = FALSE;
}
jump = TRUE;
break;
case IDCMP_NEWSIZE:
if (allocbm ())
{
cont = FALSE;
}
break;
case IDCMP_IDCMPUPDATE:
ULONG h;
GetAttr (PGA_Top, propgadget, &h);
if (++h != scalefac)
{
scalefac = h;
if (allocbm ()) cont = FALSE;
setwintitle ();
setmenu ();
}
break;
case IDCMP_MENUPICK:
cont = menupick (m.Code);
break;
case IDCMP_ACTIVEWINDOW:
SetAPen (winrp, pens[0]);
SetBPen (winrp, pens[1]);
printcoords (oldx, oldy);
printrgb (oldx, oldy);
ClearMenuStrip (mywin);
freescreensmenu (ItemAddress (menu, FULLMENUNUM (0, 1, 0)));
if (makescreensmenu ())
{
SetMenuStrip (mywin, menu);
}
else
{
cont = FALSE;
}
break;
case IDCMP_INACTIVEWINDOW:
SetAPen (winrp, pens[2]);
SetBPen (winrp, pens[3]);
printcoords (oldx, oldy);
printrgb (oldx, oldy);
break;
case IDCMP_MOUSEBUTTONS:
if (fixed)
{
if (m.Code == SELECTDOWN)
{
fixedmove = TRUE;
}
else
{
fixedmove = FALSE;
}
}
break;
case IDCMP_MOUSEMOVE:
if (fixedmove)
{
fixedX = scr->MouseX;
fixedY = scr->MouseY;
}
break;
case IDCMP_VANILLAKEY:
cont = vanillakey (m.Code);
break;
case IDCMP_RAWKEY:
rawkey (m.Code, m.Qualifier);
break;
case IDCMP_REFRESHWINDOW:
refresh ();
break;
}
if (jump)
{
break;
}
} // while (intuimsg
}
} // if (userport)
if (app_mp)
{
if (sigmask & (1 << app_mp->mp_SigBit))
{
app_clicked = FALSE;
while ((appmsg = (struct AppMessage *) GetMsg (app_mp)) != 0)
{
ReplyMsg ((struct Message *) appmsg);
app_clicked = TRUE;
}
if (app_clicked)
{
showwindow ();
}
}
}
if ((sigmask & (1 << showhidesig)) && cont)
{
if (mywin)
{
hidewindow ();
}
else
{
showwindow ();
}
}
if ((sigmask & (1 << timesig)) && cont)
{
if (mywin)
{
// refresh only if we living on the active screen
lock = LockIBase (0);
tmpscr = IntuitionBase->ActiveScreen;
UnlockIBase (lock);
if (scr == tmpscr)
{
refresh ();
}
}
}
if (sigmask & SIGBREAKF_CTRL_C)
{
cont = FALSE;
}
} // while (cont)
}
BOOL fixedFunc ()
{
if (!fixed && (item->Flags & CHECKED))
{
fixed = TRUE;
fixedX = scr->MouseX;
fixedY = scr->MouseY;
}
else if (fixed && !(item->Flags & CHECKED))
{
fixed = FALSE;
}
return TRUE;
}
BOOL fastFunc ()
{
fast = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL crosshairFunc ()
{
crosshair = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL AboutFunc ()
{
EasyRequestArgs (NULL, &es_about, NULL, era_about);
return TRUE;
}
BOOL jumpFunc ()
{
int returnvalue;
if (!(returnvalue = setupscreen (NULL)))
{
return reopenwin ();
}
else if (returnvalue == 1)
{
return TRUE; // no other screen
}
return FALSE;
}
BOOL openfilereq ()
{
APTR request;
request = AllocAslRequestTags (ASL_FileRequest,
ASLFR_InitialHeight, scr->Height / 2,
ASLFR_Screen, scr,
ASLFR_SleepWindow, TRUE,
ASLFR_Window, mywin,
ASLFR_TitleText, "Save IFF",
ASLFR_InitialDrawer, iffpath,
ASLFR_InitialFile, iffname,
ASLFR_DoSaveMode, TRUE,
ASLFR_RejectIcons, TRUE, TAG_DONE);
if (request)
{
if (AslRequest (request, NULL))
{
strncpy (iffpath, ((struct FileRequester *) request)->fr_Drawer, 255);
strncpy (iffname, ((struct FileRequester *) request)->fr_File, 108);
FreeAslRequest (request);
return TRUE;
}
}
return FALSE;
}
void write (register __d4 APTR buffer, register __d5 LONG size)
{
if (Write (fh, buffer, size) != size)
{
throw (1);
}
}
ULONG compressline (register __a3 UBYTE *src, register __a4 UBYTE *dest, ULONG size)
{
register UBYTE x, y, *tmp, *deststart;
deststart = dest;
while (size > 1)
{
if (*src == src[1])
{
y = *src++;
x = 0;
size--;
while (size && (x < 127) && (*src == y))
{
size--;
x++;
src++;
}
*dest++ = -x;
*dest++ = y;
}
else
{
tmp = dest++;
y = *src++;
x = 0;
while (size && (x < 128) && (*src != y))
{
size--;
x++;
*dest++ = y;
y = *src++;
}
*tmp = x - 1;
src--;
}
}
if (size)
{
*dest++ = 0;
*dest++ = *src;
}
return dest - deststart;
}
void saveiff ()
{
ULONG len, bodylen, packlen, vpmodeid, colors[3];;
UWORD i, j, byteoff, depth, bpr = ((innerwidth >> 3) + 2) & 0xfffe;
register UWORD x, y;
UBYTE cmap[3], *mem, *mem2, r, g, b, *offset;
struct BitMapHeader bh;
struct DisplayInfo di;
char header[] = "FORM....ILBMANNO";
char anno[] = "Written by " VERSION "\0";
try
{
// save header
depth = GetBitMapAttr (destbm, BMA_DEPTH);
write (header, strlen (header));
len = (strlen (anno) + 2) & 0xfe;
write (&len, 4);
write (anno, len);
write ("BMHD", 4);
len = sizeof (struct BitMapHeader);
write (&len, 4);
bh.bmh_Width = innerwidth;
bh.bmh_Height = innerheight;
bh.bmh_Left = bh.bmh_Top = 0;
bh.bmh_Depth = depth;
bh.bmh_Masking = 0;
bh.bmh_Compression = 1;
bh.bmh_Pad = 0;
bh.bmh_Transparent = 0;
vpmodeid = GetVPModeID (&scr->ViewPort);
if (GetDisplayInfoData (NULL, (UBYTE *) &di, sizeof (struct DisplayInfo), DTAG_DISP, vpmodeid))
{
bh.bmh_XAspect = di.Resolution.x;
bh.bmh_YAspect = di.Resolution.y;
}
else
{
bh.bmh_XAspect = bh.bmh_YAspect = 0;
}
bh.bmh_PageWidth = innerwidth;
bh.bmh_PageHeight = innerheight;
write (&bh, len);
write ("CAMG", 4);
len = 4;
write (&len, 4);
write (&vpmodeid, 4);
if (!cybergfxscreen)
{
write ("CMAP", 4);
len = 3 * (1 << depth);
write (&len, 4);
for (i = 0; i < (1 << depth); i++)
{
GetRGB32 (scr->ViewPort.ColorMap, i, 1, colors);
cmap[0] = colors[0] & 0xff;
cmap[1] = colors[1] & 0xff;
cmap[2] = colors[2] & 0xff;
write (cmap, 3);
}
}
write ("BODY....", 8);
bodylen = Seek (fh, 0, OFFSET_CURRENT) - 4;
if (cybergfxscreen)
{
// 24 Bit
mem = (UBYTE *) AllocVec (bpr * 24, 0);
mem2 = (UBYTE *) AllocVec (bpr << 1, 0);
if (mem && mem2)
{
len = 0;
for (i = 0; i < destbm->Rows; i++)
{
memset (mem, 0, bpr * 24);
offset = destbm->Planes[0] + i * bpr * 24;
for (j = 0, y = 7; j < (bpr * 24); j++, y--)
{
r = *(offset + j++);
g = *(offset + j++);
b = *(offset + j);
if (y > 7) y = 7;
byteoff = j / 24;
for (x = 0; x < 8; x++)
{
mem[x*bpr+byteoff] |= ((r >> x) & 1u) << y;
mem[(x+8)*bpr+byteoff] |= ((g >> x) & 1u) << y;
mem[(x+16)*bpr+byteoff] |= ((b >> x) & 1u) << y;
}
}
for (j = 0; j < (bpr * 24); j += bpr)
{
packlen = compressline (&mem[j], mem2, bpr);
write (mem2, packlen);
}
Move (winrp, leftoff, i + topoff);
Draw (winrp, innerwidth + leftoff - 1, i + topoff);
}
FreeVec (mem);
FreeVec (mem2);
}
else
{
throw (2);
} // if (mem)
}
else
{
mem = (UBYTE *) AllocVec (destbm->BytesPerRow << 1, 0);
if (mem)
{
if (GetBitMapAttr (destbm, BMA_FLAGS) & BMF_INTERLEAVED)
{
// interleaved
for (i = 0, len = 0; i < (destbm->Rows * depth); i++, len += destbm->BytesPerRow / depth)
{
packlen = compressline (destbm->Planes[0] + len, mem, destbm->BytesPerRow / depth);
write (mem, packlen);
if (!(i % depth))
{
Move (winrp, leftoff, i / depth + topoff);
Draw (winrp, innerwidth + leftoff - 1, i / depth + topoff);
}
}
}
else
{
len = 0;
for (i = 0; i < destbm->Rows; i++)
{
for (j = 0; j < depth; j++)
{
packlen = compressline (destbm->Planes[j] + len, mem, destbm->BytesPerRow);
write (mem, packlen);
}
len += destbm->BytesPerRow;
Move (winrp, leftoff, i + topoff);
Draw (winrp, innerwidth + leftoff - 1, i + topoff);
}
}
FreeVec (mem);
}
else
{
throw (3);
}
} // if (cybergfxscreen)
if (Seek (fh, 0, OFFSET_CURRENT) & 1)
{
r = 0x80;
write (&r, 1);
}
len = Seek (fh, 4, OFFSET_BEGINNING) - 8;
write (&len, 4);
Seek (fh, bodylen, OFFSET_BEGINNING);
len = len - bodylen + 4;
write (&len, 4);
}
catch (int) { }
}
BOOL saveFunc ()
{
BPTR dirlock, olddirlock;
ULONG reg;
if (openfilereq ())
{
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
dirlock = Lock (iffpath, SHARED_LOCK);
if (dirlock)
{
olddirlock = CurrentDir (dirlock);
fh = Open (iffname, MODE_NEWFILE);
if (fh)
{
mywin->Flags &= ~SIZEGADGET;
reg = GetAPen (winrp);
SetAPen (winrp, 0);
saveiff ();
Close (fh);
BltBitMapRastPort (destbm, 0, 0, winrp, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
SetAPen (winrp, reg);
mywin->Flags |= SIZEGADGET;
}
else
{
error ("Can't create '%s'.", iffname);
}
CurrentDir (olddirlock);
UnLock (dirlock);
}
else
{
error ("Can't lock '%s'.", iffpath);
}
}
return TRUE;
}
BOOL coordsFunc ()
{
if (!coords && (item->Flags & CHECKED))
{
coords = TRUE;
}
else if (coords && !(item->Flags & CHECKED))
{
coords = FALSE;
}
else
{
return TRUE; // nothing changed
}
return reopenwin ();
}
BOOL gridFunc ()
{
grid = (item->Flags & CHECKED) != 0;
setupgrid ();
return TRUE;
}
BOOL showrgbFunc ()
{
if (!showrgb && (item->Flags & CHECKED))
{
showrgb = TRUE;
}
else if (showrgb && !(item->Flags & CHECKED))
{
showrgb = FALSE;
}
else
{
return TRUE; // nothing changed
}
return reopenwin ();
}
BOOL enableFunc ()
{
if (item->Flags & CHECKED)
{
ActivateCxObj (broker, 1);
enable = TRUE;
}
else if (!(item->Flags & CHECKED))
{
ActivateCxObj (broker, 0);
enable = FALSE;
}
return TRUE;
}
BOOL hideoncloseFunc ()
{
hideonclose = (item->Flags & CHECKED) != 0;
return TRUE;
}
BOOL hideFunc ()
{
hidewindow ();
jump = TRUE;
return TRUE;
}
BOOL QuitFunc ()
{
return FALSE;
}
BOOL argbool (char **argv, char *name, BOOL def)
{
char *value = (char *) FindToolType ((UBYTE **) argv, name);
if (value)
{
if ((MatchToolValue (value, "YES")) || (MatchToolValue (value, "ON"))) return TRUE;
if ((MatchToolValue (value, "OFF")) || (MatchToolValue (value, "NO"))) return FALSE;
}
return def;
}
LONG argint (char **argv, UBYTE *name, LONG def)
{
LONG returnvalue;
APTR value = FindToolType ((UBYTE **) argv, name);
if (value)
{
if (StrToLong ((UBYTE *) value, &returnvalue))
{
return returnvalue;
}
}
return def;
}
void argstring (char *result, char **argv, char *name, size_t size = 50)
{
char *value = FindToolType ((UBYTE **) argv, name);
if (value)
{
strncpy (result, value, size);
}
}
void readargs ()
{
// first time always the tooltypes will be evaluated
// if we started from Cli the tooltypes can be overloaded
char **argv;
struct DiskObject *programicon;
struct RDArgs * rdargs;
struct DrawInfo *drawinfo;
LONG a[19];
long *args = a;
wintop = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
// make window as square as possible
drawinfo = GetScreenDrawInfo (scr);
if (drawinfo)
{
innerheight = innerwidth * drawinfo->dri_Resolution.X / drawinfo->dri_Resolution.Y;
FreeScreenDrawInfo (scr, drawinfo);
}
if (Cli ())
{
GetProgramName (programname, 108);
}
else
{
strcpy (programname, thistask->tc_Node.ln_Name);
}
IconBase = OpenLibrary ("icon.library", 37);
if (IconBase)
{
programicon = GetDiskObject (programname);
if (programicon)
{
argv = programicon->do_ToolTypes;
newbroker.nb_Pri = argint (argv, "CX_Priority", newbroker.nb_Pri);
fast = argbool (argv, "Fast", fast);
maxscalefac = argint (argv, "MaxScaleFactor", maxscalefac);
scalefac = argint (argv, "ScaleFactor", scalefac);
winleft = argint (argv, "WinLeft", winleft);
wintop = argint (argv, "WinTop", wintop);
innerheight = argint (argv, "WinHeight", innerheight);
innerwidth = argint (argv, "WinWidth", innerwidth);
coords = argbool (argv, "Coordinates", coords);
crosshair = argbool (argv, "Crosshair", crosshair);
argstring (setoriginkey, argv, "SetOriginKey");
argstring (resetoriginkey, argv, "ResetOriginKey");
fixed = argbool (argv, "Fixed", fixed);
argstring (showhidekey, argv, "ShowHideKey");
hide = argbool (argv, "Iconify", hide);
hideonclose = argbool (argv, "IconifyOnClose", hideonclose);
grid = argbool (argv, "Grid", grid);
showrgb = argbool (argv, "ShowRGB", showrgb);
argstring (iffpath, argv, "IFFFile", 255);
FreeDiskObject (programicon);
}
CloseLibrary (IconBase);
}
if (Cli ())
{
memset (args, '\0', 19 * sizeof (LONG));
args[1] = fast;
args[8] = coords;
args[9] = crosshair;
args[12] = fixed;
args[14] = hide;
args[15] = hideonclose;
args[16] = grid;
args[17] = showrgb;
rdargs = ReadArgs (Template, args, NULL);
if (rdargs)
{
if (*args) newbroker.nb_Pri = *args;
args++;
fast = *args++;
if (*args) maxscalefac = *(LONG *) *args;
if (*++args) scalefac = *(LONG *) *args;
if (*++args) winleft = *(LONG *) *args;
if (*++args) wintop = *(LONG *) *args;
if (*++args) innerwidth = *(LONG *) *args;
if (*++args) innerheight = *(LONG *) *args;
args++;
coords = *args++;
crosshair = *args++;
if (*args) strncpy (setoriginkey, (char *) *args, 50);
if (*++args) strncpy (resetoriginkey, (char *) *args, 50);
args++;
fixed = *args++;
if (*args) strncpy (showhidekey, (char *) *args, 50);
args++;
hide = *args++;
hideonclose = *args++;
grid = *args++;
showrgb = *args++;
if (*args) strncpy (iffpath, (char *) *args, 255);
FreeArgs (rdargs);
}
}
if (maxscalefac < 5) maxscalefac = 5;
// not lower than innerheight or innerwidth
// otherwise 'innerheight / scalefac' or 'innerwidth / scalefac'
// can go to 0 -> 'AllocBitMap ()' failed
if (maxscalefac > MINHEIGHT) maxscalefac = MINHEIGHT;
if (scalefac > maxscalefac) scalefac = maxscalefac;
if (innerheight < MINHEIGHT) innerheight = MINHEIGHT;
if (innerwidth < MINWIDTH) innerwidth = MINWIDTH;
char *str;
str = strrchr (iffpath, '/');
if (str)
{
strncpy (iffname, str + 1, 108);
*str = '\0';
}
else if ((str = strrchr (iffpath, ':')) != 0)
{
strncpy (iffname, ++str, 108);
*str = '\0';
}
else
{
strncpy (iffname, iffpath, 108);
iffpath[0] = '\0';
}
}
void main ()
{
if ((CxBase = OpenLibrary ("commodities.library", 37)) != 0)
{
if ((GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 39)) != 0)
{
if ((GadToolsBase = OpenLibrary ("gadtools.library", 37)) != 0)
{
if ((WorkbenchBase = OpenLibrary ("workbench.library", 37)) != 0)
{
if ((AslBase = OpenLibrary ("asl.library", 37)) != 0)
{
CyberGfxBase = OpenLibrary ("cybergraphics.library", 40);
InitRastPort (&destrp);
SetAPen (&destrp, 0);
InitRastPort (&maskrp);
SetDrMd (&maskrp, COMPLEMENT);
thistask = FindTask (NULL);
if ((topazfont = OpenFont (&topaz_attr)) != 0)
{
if (!setupscreen (NULL))
{
readargs ();
getoffsets ();
try
{
if (!hide)
{
if (!openwin ()) throw 1;
if (allocbm ()) throw 2;
}
if ((timesig = AllocSignal (-1L)) != -1)
{
if ((showhidesig = AllocSignal (-1L)) != -1)
{
if (initbroker ())
{
processmsg ();
DeleteCxObjAll (broker);
DeleteMsgPort (broker_mp);
}
FreeSignal (showhidesig);
}
FreeSignal (timesig);
}
else
{
error ("Can't allocate signal");
}
} // try
catch (int) { }
closewin ();
CloseDownScreen ();
freeappicon ();
}
CloseFont (topazfont);
if (screenfont)
{
CloseFont (screenfont);
}
}
else
{
error ("Can't open Topaz.font");
}
if (CyberGfxBase)
{
CloseLibrary (CyberGfxBase);
}
CloseLibrary (AslBase);
}
else
{
error ("Can't open '%s' version %ld or higher.", "asl.library", 37L);
}
CloseLibrary (WorkbenchBase);
}
else
{
error ("Can't open '%s' version %ld or higher.", "workbench.library", 37L);
}
CloseLibrary (GadToolsBase);
}
else
{
error ("Can't open '%s' version %ld or higher.", "gadtools.library", 37L);
}
CloseLibrary ((struct Library *) GfxBase);
}
else
{
error ("Can't open '%s' version %ld or higher.", "graphics.library", 39L);
}
CloseLibrary (CxBase);
}
else
{
error ("Can't open '%s' version %ld or higher.", "commodities.library", 37L);
}
}